﻿
using System;
using System.Web;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Text;
using System.Threading;

namespace Caifu.Fx
{
	/// <summary>
	/// 本类用于产生随机的验证码
	/// </summary>
	public class ValidationCode
	{
		private string FontFace = "微软雅黑";
		private int FontSize = 15;
		private Color foreColor = Color.FromArgb(5, 84, 145);
		private Color backforeColor = Color.FromArgb(255, 255, 255);
		private Color backColor = Color.FromArgb(113, 158, 205);
		private Color mixedLineColor = Color.FromArgb(255, 255, 255);
		private int mixedLineWidth = 1;
		private int mixedLineCount = 3;
		Graphics g = null;
		int ImgWidth;
		int ImgHeight;
		Random RandomServiceProvider;

		//用户存取验证码字符串
		private string validationCode = String.Empty;
		public string Code
		{
			get { return validationCode; }
		}

		public ValidationCode(int length)
		{
			Thread.Sleep(15);
			RandomServiceProvider = new Random();
			this.ImgHeight = this.FontSize * 2;
			this.ImgWidth = this.FontSize * (length + 2);
			this.Next(length);
		}

		#region 根据指定长度，返回随机验证码

		/// <summary>
		/// 根据指定长度，返回随机验证码
		/// </summary>
		/// <param name="length">制定长度</param>
		/// <returns>随即验证码</returns>
		void Next(int length)
		{
			this.validationCode = GetRandomCode(length);
		}
		#endregion

		#region 根据指定长度及背景图片样式，返回带有随机验证码的图片对象

		/// <summary>
		/// 根据指定长度及背景图片样式，返回带有随机验证码的图片对象
		/// </summary>
		/// <param name="length">指定长度</param>
		/// <param name="hatchStyle">背景图片样式</param>
		/// <returns>Image对象</returns>
		public Image NextImage(bool allowMixedLines)
		{

			//生成背景图片
			Bitmap CodeBitmap = new Bitmap(ImgWidth, ImgHeight);
			g = Graphics.FromImage(CodeBitmap);
			this.DrawBackground();
			this.DrawValidationCode();
			if (allowMixedLines)
				this.DrawMixedLine();
			return (System.Drawing.Image)CodeBitmap;
		}
		#endregion

		#region 内部方法：绘制验证码背景
		private void DrawBackground()
		{
			//设置填充背景时用的笔刷
			HatchBrush hBrush = new HatchBrush((HatchStyle)RandomServiceProvider.Next(1, 53),
				backforeColor, backColor);

			//填充背景图片
			g.FillRectangle(hBrush, 0, 0, this.ImgWidth, this.ImgHeight);
		}
		#endregion

		#region 内部方法：绘制验证码
		private void DrawValidationCode()
		{
			g.DrawString(this.Code, new Font(FontFace, FontSize),
				new SolidBrush(this.foreColor), 0, 1);
		}
		#endregion

		#region 内部方法：绘制干扰线条

		/// <summary>
		/// 绘制干扰线条
		/// </summary>
		private void DrawMixedLine()
		{
			for (int i = 0; i < mixedLineCount; i++)
			{
				g.DrawBezier(new Pen(new SolidBrush(mixedLineColor), mixedLineWidth),
					RandomPoint(), RandomPoint(), RandomPoint(), RandomPoint());
			}
		}
		#endregion

		#region 内部方法：返回指定长度的随机验证码字符串

		/// <summary>
		/// 根据指定大小返回随机验证码
		/// </summary>
		/// <param name="length">字符串长度</param>
		/// <returns>随机字符串</returns>
		private string GetRandomCode(int length)
		{
			StringBuilder sb = new StringBuilder(length);
			for (int i = 0; i < length; i++)
			{
				sb.Append((char)RandomAZ09());
			}
			return sb.ToString();
		}
		#endregion

		#region 内部方法：产生随机数和随机点

		/// <summary>
		/// 产生0-9A-Z的随机字符代码
		/// </summary>
		/// <returns>字符代码</returns>
		private int RandomAZ09()
		{
			int result = 49;
			int i = RandomServiceProvider.Next(3);
			switch (i)
			{
				case 0:
					result = RandomServiceProvider.Next(49, 58);
					break;
				case 1:
					result = RandomServiceProvider.Next(65, 79);
					break;
				case 2:
					result = RandomServiceProvider.Next(80, 91);
					break;
			}
			return result;
		}

		/// <summary>
		/// 返回一个随机点，该随机点范围在验证码背景大小范围内
		/// </summary>
		/// <returns>oint对象</returns>
		private Point RandomPoint()
		{
			Point point = new Point(RandomServiceProvider.Next(this.ImgWidth),
				RandomServiceProvider.Next(this.ImgHeight));
			return point;
		}
		#endregion
	}
}
